//
// Created by subject on 2025/2/19.
//

#include "LlmManager.h"
#include <iostream> //用于调试输出
#include <fstream>
#include <cstring>
#include <jni.h>


#define PROMPT_TEXT_PREFIX "<｜begin▁of▁sentence｜><｜User｜>"
#define PROMPT_TEXT_POSTFIX "<｜Assistan"

//私有构造函数
LlmManager::LlmManager() : llmHandle(nullptr), initialized(false){
    LOGI("LlmManager instance created.");
}
//私有析构函数
LlmManager::~LlmManager() {
    destroy();
    LOGI("LlmManager instance destroyed.");
}

//静态方法：获取单例实例
LlmManager& LlmManager::getInstance() {
    static LlmManager instance; //静态局部变量，保证只初始化一次
    return instance;
}

bool LlmManager::initialize(const std::string &modelPath, int maxNewTokens, int maxContextLen, LLMResultCallback callback) {
    if(initialized){
        LOGE("LlmManager is already initialized!");
        return false;
    }
    RKLLMParam param = rkllm_createDefaultParam();
    param.model_path = modelPath.c_str();
    param.top_k = 1;
    param.top_p = 0.95;
    param.temperature = 0.8;
    param.repeat_penalty = 1.1;
    param.frequency_penalty = 0.0;
    param.presence_penalty = 0.0;
    param.max_new_tokens = maxNewTokens;
    param.max_context_len = maxContextLen;
    param.skip_special_token = true;
    param.extend_param.base_domain_id = 0;

    int ret = rkllm_init(&llmHandle, &param, callback);
    if(ret == 0){
        LOGI("LlmManager initialized successfully!");
        initialized = true;

        memset(&inferParams, 0, sizeof(RKLLMInferParam));
        inferParams.mode = RKLLM_INFER_GENERATE;
        return true;
    }else{
        LOGE("Failed to initialize LlmManager!");
        return false;
    }
}

void LlmManager::run(const std::string &input) {
    if(!initialized){
        LOGE("LlmManager is not initialized!");
        return;
    }
    std::string text = PROMPT_TEXT_PREFIX + input + PROMPT_TEXT_POSTFIX;
    RKLLMInput rkllmInput;
    rkllmInput.input_type = RKLLM_INPUT_PROMPT;
    rkllmInput.prompt_input = (char*)text.c_str();

    LOGD("robot: ");
    rkllm_run(llmHandle, &rkllmInput, &inferParams, nullptr);
}

void LlmManager::destroy() {
    if(llmHandle != nullptr){
        rkllm_destroy(llmHandle);
        llmHandle = nullptr;
        initialized = false;
        LOGI("LlmManager destroyed!");
    }
}

bool LlmManager::isInitialized() {
    return initialized;
}






